package com.jack.basetech;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Set;

/**
 * Created by zhang_j on 2020/11/3
 */
public class JacksonUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(JacksonUtil.class);
    private static final String DYNC_FILTER = "DYNC_FILTER";
    private static final String DYNC_INCLUDE = "DYNC_INCLUDE";
    private static final String LABEL_PRO_FILTER = "collegeName,schema,sLabels,tLabels,vLabels,yLabels,StoreLabels,VehicleLabels";
    @JsonFilter(DYNC_FILTER)
    private interface DynamicFilter {
    }

    @JsonFilter(DYNC_INCLUDE)
    private interface DynamicInclude {
    }

    public static String toJsonLabelFilter(Object obj){
        return toJsonIgnor(obj, LABEL_PRO_FILTER);
    }

    private static String toJsonIgnor(Object obj, String properties) {
        ObjectMapper mapper = new ObjectMapper();
        if (obj != null) {
            try {
                mapper.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_FILTER,
                        SimpleBeanPropertyFilter.serializeAllExcept(properties.split(","))));
                mapper.addMixIn(obj.getClass(), DynamicFilter.class);

//                MAPPER.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_INCLUDE,
//                        SimpleBeanPropertyFilter.filterOutAllExcept(property.split(","))));
//                MAPPER.addMixIn(tClass, DynamicInclude.class);

                return mapper.writeValueAsString(obj);
            } catch (Exception ex) {
                LOGGER.error("JacksonUtil", ex, obj);
            }
        }
        return null;
    }

    public static String toJson(Object obj){
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            LOGGER.error("JacksonUtil", e, obj);
            return null;
        }
    }

    public static String toJson(String body, String field){
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            JsonNode node = objectMapper.readTree(body);
            JsonNode jsonNode = node.get(field);
            if(jsonNode != null){
                return jsonNode.asText();
            }
        } catch (Exception e) {
            LOGGER.error("JacksonUtil", e, body, field);
            return null;
        }
        return null;
    }

    public static <T> T toJson(String json, Class<T> ca) {
        ObjectMapper objectMapper = new ObjectMapper();
        if (json == null) {
            return null;
        }
        try {
            return objectMapper.readValue(json, ca);
        } catch (Exception e) {
            LOGGER.error("JacksonUtil", e, json, ca.getName());
            return null;
        }
    }

    public static <T> List<T> getObjList(String str, Class<T> clazz) {
        ObjectMapper objectMapper = new ObjectMapper();
        if(StringUtils.isBlank(str)){
            return null;
        }
        try {
            JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, clazz);
            return objectMapper.readValue(str, javaType);
        } catch (Exception e) {
            LOGGER.error("JacksonUtil", e, str, clazz.getName());
            return null;
        }
    }

    public static <T> Set<T> getObjSet(String str, Class<T> clazz) {
        ObjectMapper objectMapper = new ObjectMapper();
        if(StringUtils.isBlank(str)){
            return null;
        }
        try {
            JavaType javaType = objectMapper.getTypeFactory().constructParametricType(Set.class, clazz);
            return objectMapper.readValue(str, javaType);
        } catch (Exception e) {
            LOGGER.error("JacksonUtil", e, str, clazz.getName());
            return null;
        }
    }
}
